<?php
Class error {
	
	const TYPE_NOTICE = 1;
	const TYPE_WARNING = 2;
	const TYPE_FATAL = 3;
	const TYPE_ACL = 4;
	
	/**
	 * Error handler
	 * see: http://codingforums.com/showthread.php?t=147060
	 */
	static function handler($errno, $errstr, $errfile, $errline, $errcontext) {
		
		// if error has been supressed with an @
	    if (error_reporting() == 0) {
	        return;
	    }
	    
		$ret = null;
//	    if(!(error_reporting() & $errno)) 
//	        return; 
	    switch($errno) { 
	    case E_STRICT       : 
	    case E_NOTICE       :
	    	return;
	    case E_WARNING      : 
	    case E_USER_WARNING :  
	    case E_USER_NOTICE  : 
	        $type = 'warning'; 
	        $fatal = false; 
	        break; 
	    default             : 
	        $type = 'fatal error'; 
	        $fatal = true; 
	        break; 
	    } 
	    if(php_sapi_name() == 'cli') { 
	        $ret .= 'Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' <b>' . $errline . '</b>:' . "\n"; 
	        foreach(array_reverse(debug_backtrace()) as $item) 
	            $ret .= '  ' . (isset($item['file']) ? $item['file'] : '<unknown file>') . ' <b>' . (isset($item['line']) ? $item['line'] : '<unknown line>') . '</b> calling ' . $item['function'] . '()' . "\n"; 
	    } else {  
	        $ret .= '  Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' <b>' . $errline . '</b>:' . "\n"; 
	        $ret .= '  <ol>' . "\n"; 
	        foreach(array_reverse(debug_backtrace()) as $item) 
	            $ret .= '    <li>' . (isset($item['file']) ? $item['file'] : '<unknown file>') . ' <b>' . (isset($item['line']) ? $item['line'] : '<unknown line>') . '</b> calling ' . $item['function'] . '()</li>' . "\n"; 
	        $ret .= '  </ol>' . "\n";  
	    }
	    if($fatal) {
	    	error::fatal($ret); 
     		exit(1);
		} else {
			error::warning($ret);
		}
		error_log(sprintf("PHP %s:  %s in %s on line %d", $errno, $errstr, $errfile, $errline));
	}
	
	static function warning($msg) {
		html::messageBox($msg, "Warning", "ca5600");
		error::log(error::TYPE_WARNING, $msg);
	}
	
	static function fatal($msg) {
		html::messageBox($msg, "Error", "800000");
		error::log(error::TYPE_FATAL, $msg);
		die();
	}
	
	static function http404() {
		self::httpStatusRedirect("404");
	}
	
	static function httpStatusRedirect($code) {
		//header("HTTP/1.0 ".$code." ".self::getHTTPResponseType($code));
		ob_clean();
		header("Status: $code");
		header("Content-type: text/html; charset=UTF-8");
		$_SERVER['REDIRECT_STATUS'] = $code;
		include("errordocument.php");
		die();
	}
	
	static function log($type, $msg) {
		$line = date(DATE_ISO8601)."; ";
		$line .= "(".error::getErrorType($type)."); ";
		$line .= "\"".addslashes(str_replace("\n", ";", $msg))."\"; ";
		$line .= "\$_GET = ".str_replace("\n", "", serialize($_GET))."; ";
		$line .= "\$_POST = ".str_replace("\n", "", serialize($_POST))."; ";
		$line .= "\$_SESSION = ".str_replace("\n", "", serialize($_SESSION))."; ";
		$line .= "\$_COOKIE = ".str_replace("\n", "", serialize($_COOKIE))."; ";
		$line .= "\$_SERVER = ".str_replace("\n", "", serialize($_SERVER))."; ";
		$line .= "\r\n";
		$fp = fopen('logs/error.log', 'a');
		fwrite($fp, $line);
		fclose($fp);
	}
	
	static function getErrorType($type) {
		switch ($type) {
			case 1: return "E_ERROR";
			case 2: return "E_WARNING";
			case 4: return "E_PARSE";
			case 8: return "E_NOTICE";
			case 16: return "E_CORE_ERROR";
			case 32: return "E_CORE_WARNING";
			case 64: return "E_COMPILE_ERROR";
			case 128: return "E_COMPILE_WARNING";
			case 256: return "E_USER_ERROR";
			case 512: return "E_USER_WARNING";
			case 1024: return "E_USER_NOTICE";
			case 2048: return "E_STRICT";
			case 4096: return "E_RECOVERABLE_ERROR";
			case 8192: return "E_DEPRECATED";
			case 16384: return "E_USER_DEPRECATED";
			case 30719: return "E_ALL";
		}
	}
	
	static function getHTTPResponseType($code) {
		switch ($code) {
			case 400: return "Bad Request";
			case 401: return "Unauthorized";
			case 403: return "Forbidden";
			case 404: return "Not Found";
			case 500: return "Internal Server Error";
			case 501: return "Not Implemented";
			case 502: return "Bad Gateway";
			case 503: return "Service Unavailable";
			case 504: return "Bad Timeout";
		}
	}
	
}
?>